package com.witmed.controller.chat;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;

@ServerEndpoint("/chat/{userId}")
public class ChatServer {
	private static int onlineCount = 0;
	private static Map<String, ChatServer> guestMap = new ConcurrentHashMap<String, ChatServer>();
	private static Map<String, ChatServer> serverMap = new ConcurrentHashMap<String, ChatServer>();

	private Session session;
	private String clientId;
	private String userType;

	@OnOpen
	public void open(@PathParam("userId") String userId, Session userSession) {
		this.clientId = userId;
		this.session = userSession;
		this.userType = userSession.getQueryString();

		if (this.userType.equals("1")) {
			serverMap.put(clientId, this);
		} else {
			guestMap.put(clientId, this);
		}

		addOnlineCount();
	}

	@OnMessage
	public void getMessage(String message, Session userSession) throws IOException {
		sendMessage(clientId, message);
	}

	@OnClose
	public void close(Session userSession) {
		if (this.userType.equals("1")) {
			serverMap.remove(clientId);
		} else {
			guestMap.remove(clientId);
		}
		subOnlineCount();
	}

	@OnError
	public void error(Session session, Throwable error) {
		System.out.println("Error: error...");
	}

	private void sendMessage(String userId, String msg) throws IOException {
		ChatServer sendObj = null;
		ObjectMapper mapper = new ObjectMapper();
		ChatMessage msgObj = null;
		try {
			msgObj = mapper.readValue(msg, ChatMessage.class);
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		}

		if (userType.equals("0")) {
			sendObj = serverMap.get(msgObj.getId());
		} else {
			sendObj = guestMap.get(msgObj.getId());
		}

		if (sendObj == null) {
			return;
		}

		String json = "";
		long curTime = System.currentTimeMillis();
		JsonNode root = mapper.createObjectNode();

		if (userType.equals("0")) {
			((ObjectNode) root).put("username", "咨询客户");
			((ObjectNode) root).put("avatar", "static/images/visitor.jpg");
		} else {
			((ObjectNode) root).put("username", "在线客服");
			((ObjectNode) root).put("avatar", "static/images/brief.gif");
		}

		((ObjectNode) root).put("id", clientId);
		((ObjectNode) root).put("type", "kefu");
		((ObjectNode) root).put("content", msgObj.getMsg());
		((ObjectNode) root).put("mine", false);
		((ObjectNode) root).put("cid", 0);
		((ObjectNode) root).put("fromid", clientId);
		((ObjectNode) root).put("timestamp", curTime);
		try {
			json = mapper.writeValueAsString(root);
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		}

		sendObj.session.getAsyncRemote().sendText(json);
	}

	public static synchronized int getOnlineCount() {
		return onlineCount;
	}

	public static synchronized int addOnlineCount() {
		return onlineCount++;
	}

	public static synchronized int subOnlineCount() {
		return onlineCount--;
	}
}
